package com.bigcat.gulimall.demo.utils;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.bigcat.gulimall.demo.utils.excel.ExcelExportStylerImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * @author sufer_yuan
 * @since 2022/9/8
 */

/**
 * EXCEL工具类
 */
@Slf4j
public class ExcelUtils {

    /**
     * 下载模板文件:需要兼容浏览器
     */
//    public static void downFile(String path, String filename, HttpServletRequest request,
//                                HttpServletResponse response) {
//
//        InputStream fis = null;
//        OutputStream os = null;
//        try {
//            File file = new File(path);// path
//            String agent = request.getHeader("User-Agent").toUpperCase();
//            if (agent.contains(SymbolConstants.FIREFOX)) {
//                filename = new String(filename.getBytes(), StandardCharsets.ISO_8859_1);// firefox浏览器
//            } else if (agent.contains(SymbolConstants.MSIE)) {
//                filename = URLEncoder.encode(filename, "UTF-8");// IE浏览器
//            } else if (agent.contains(SymbolConstants.CHROME)) {
//                filename = URLEncoder.encode(filename, "UTF-8");// chrome谷歌
//            } else {
//                filename = URLEncoder.encode(filename, "UTF-8");// 其他（包括360）
//            }
//            response.reset();
//            // 先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,这个文件名称用于浏览器的下载框中自动显示的文件名
//            response.addHeader("Content-Disposition",
//                    "attachment;filename=" + new String(filename.replaceAll(" ", "").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
//            response.addHeader("Content-Length", "" + file.length());
//            response.setContentType("application/octet-stream");
//
//            //文件流处理
//            fis = new BufferedInputStream(new FileInputStream(path));
//            byte[] buffer = new byte[5];
//            int hasRead;
//            os = new BufferedOutputStream(response.getOutputStream());
//            while ((hasRead = fis.read(buffer)) != -1){
//                os.write(buffer,0, hasRead);
//            }
//            os.flush();
//            os.close();
//            fis.close();
//        } catch (Exception e) {
//            log.error("下载模板文件异常！", e);
//        } finally {
//            if (os != null) {
//                try {
//                    os.flush();
//                    os.close();
//                } catch (IOException e) {
//                    log.error("OutputStream输出流关闭异常!", e);
//                }
//            }
//            if (fis != null) {
//                try {
//                    fis.close();
//                } catch (IOException e) {
//                    log.error("InputStream输入流关闭异常!", e);
//                }
//            }
//        }
//    }

    /**
     * list集合导出
     *
     * @param isCreateHeader 是否创建头
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, boolean isCreateHeader, HttpServletResponse response) {
        ExportParams exportParams = new ExportParams(title, sheetName);
        exportParams.setCreateHeadRows(isCreateHeader);
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }

    /**
     * list导出excel
     *
     * @param list      导出对象的list
     * @param title     表格内的头标题（自动合并单元格），如果为null则不生成
     * @param sheetName 工作簿名称，可以为null
     * @param pojoClass list对象
     * @param fileName  文件名称，必须有".xls"文件格式
     * @param response  http的response
     */
    public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName, HttpServletResponse response) {
        ExportParams exportParams = new ExportParams(); //控制导出的样式等等ExportParams
        exportParams.setTitle(title);
        exportParams.setSheetName(sheetName);
        exportParams.setStyle(ExcelExportStylerImpl.class); //将自定义的样式导入
        defaultExport(list, pojoClass, fileName, response, exportParams);
    }

    public static void exportExcel(List<?> list, String title, String path, String sheetName, Class<?> pojoClass, String fileName) {
        ExportParams exportParams = new ExportParams(); //控制导出的样式等等ExportParams
        exportParams.setTitle(title);
        exportParams.setSheetName(sheetName);
        exportParams.setType(ExcelType.XSSF);
        exportParams.setStyle(ExcelExportStylerImpl.class); //将自定义的样式导入
        defaultExport(list, pojoClass, path, fileName, exportParams);
    }

    /**
     * map集合导出
     */
    public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
        defaultExport(list, fileName, response);
    }

    /**
     * 默认导出样式
     *
     * @param exportParams 可以自定义导出样式
     */
    private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName, HttpServletResponse response, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) ;
        downLoadExcel(fileName, response, workbook);
    }

    /**
     * 导出到本地指定目录下
     *
     * @param list 数据
     * @param pojoClass 实例对象
     * @param path 路径
     * @param fileName 文件名
     * @param exportParams 导出参数
     */
    private static void defaultExport(List<?> list, Class<?> pojoClass, String path, String fileName, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook == null) {
            return;
        }
        File file = new File(path + fileName);
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(file);
            workbook.write(fileOutputStream);
            workbook.close();
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            try {
                workbook.close();
                fileOutputStream.flush();
                fileOutputStream.close();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }

    }

    /**
     * 下载excel表格：与downFile方法一样，没有做浏览器兼容给处理
     */
    public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            log.error("easyPoi-现在加载excel异常!", e);
        }
    }

    /**
     * map集合默认导出
     */
    private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {
        Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);
        if (workbook != null) ;
        downLoadExcel(fileName, response, workbook);
    }

    /**
     * 导入文件
     *
     * @param filePath   文件路径
     * @param titleRows  表格标题所占行数
     * @param headerRows 表头所占行数
     * @param pojoClass  类型
     * @param <T>        泛型
     * @return 导入后的结果
     */
    public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
        if (StringUtils.isBlank(filePath)) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);
        } catch (NoSuchElementException e) {
            log.error("easyPoi-导入excel异常!模板不能为空", e);
        } catch (Exception e) {
            log.error("easyPoi-导入excel异常!", e);
        }
        return list;
    }

    /**
     * 导入文件
     *
     * @param file       上传的文件
     * @param titleRows  表格标题所占行数
     * @param headerRows 表头所占行数
     * @param pojoClass  类型
     * @param <T>        泛型
     * @return 导入后的结果
     */
    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
        if (file == null) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows); //控制导入的行数、工作簿等等ImportParams
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
        } catch (NoSuchElementException e) {
            log.error("easyPoi-导入excel异常!excel文件不能为空", e);
        } catch (Exception e) {
            log.error("easyPoi-导入excel异常!", e);
        }
        return list;
    }

//    /**
//     * 大数量导出，最大支持一百万
//     * @param entity
//     *            表格标题属性
//     * @param pojoClass
//     *            Excel对象Class
//     * @param dataSet
//     *            Excel对象数据List
//     */
//    public static Workbook exportBigExcel(ExportParams entity, Class<?> pojoClass,
//                                          Collection<?> dataSet) {
//        ExcelBatchExportServer batachServer = ExcelBatchExportServer
//                .getExcelBatchExportServer(entity, pojoClass);
//        return batachServer.appendData(dataSet);
//    }
//
//    /**
//     * 关闭大数量导出
//     */
//    public static void closeExportBigExcel() {
//        ExcelBatchExportServer batachServer = ExcelBatchExportServer.getExcelBatchExportServer(null,
//                null);
//        batachServer.closeExportBigExcel();
//    }
}

